不好的解法一:只适合于单线程环境

public class Singleton{
    private static Singleton instance;
    private Singleton(){}

    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }

        return instance;
    }
}

这种写法使用了懒加载(惰性加载)模式,当需要使用到的时候在进行判断,然后创建实例。

这种写法存在的问题是:当有多个线程并发调用 getInstance() 方法的时候,就会创建多个实例。

不好的写法二:虽然在多线程环境中能工作,但效率不高

public class Singleton{
    private Singleton(){}
    private static Singleton instance;

    public static synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }

        return instance;
    }
}

加上了 synchronized 关键字,解决了多实例的问题,但是并不够高效。

静态内部类

public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE; 
    }  
}

《Effective Java》上所推荐的。

这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 JDK 版本。

使用枚举

public enum EasySingleton{
    INSTANCE;
}

参考资料

  1. 如何正确地写出单例模式 - Jark's blog
  2. Java Singletons Using Enum
  3. 5种JAVA单例模式的实现、原理和演化

results matching ""

    No results matching ""